import os
from importlib import import_module
from typing import Dict

import json5
from store.IStoreService import IStoreService
from store.StoreFactory import StoreFactory
from utils.CarHttp import CarHttp
from utils.CarUtil import CarUtil
from utils.LogUtil import LogUtil

from entry.ICar import ICar


class Car(ICar):

  # 获取 ICar 实例
  @classmethod
  @property
  def instance(cls) -> ICar:
    car = cls()
    return car

  # 初始化
  def __init__(self, config: Dict | str = None) -> None:
    if isinstance(config, str):
      self.config = self.initConfig(config)
    elif isinstance(config, dict):
      self.config = config
    self.initHttpConfig()
    self.initStoreService()

  #region properties

  __config: Dict = dict()
  __http: CarHttp = CarHttp(__config)
  __storeService: IStoreService

  @property
  def config(self) -> Dict:
    return self.__config

  @config.setter
  def config(self, other) -> None:
    self.__config = other

  @property
  def http(self) -> CarHttp:
    return self.__http

  def mode(self) -> str:
    return self.__config.get("mode", "DEBUG").upper()

  def storeService(self) -> IStoreService:
    return self.__storeService

  #endregion

  #region 帮助方法

  # 调试输出
  # def d_print(self, msg: str, obj: (Any | None) = None) -> bool:
  #   """调试输出，debug_print

  #   Args:
  #       msg (str): 信息
  #       obj (Any  |  None, optional): 判断对象，对象为None则不输出打印信息. Defaults to None.

  #   Returns:
  #       bool: 是否打印信息成功
  #   """

  #   r: bool = True
  #   if self.mode == 'DEBUG' and not obj:
  #     print(msg)
  #     r = False
  #   return r

  def finish(self, msg: str = '爬取任务全部完成') -> None:
    print(f'### {msg}')

  #endregion

  #region 核心功能

  # 初始化内部变量
  def initInteriorVar(self) -> None:
    """
    初始化内部变量
    """

  # 初始化数据存储服务
  def initStoreService(
      self,
      storeService: IStoreService = None
  ) -> IStoreService:
    # self.storeService = services.DataService(self.config)

    if storeService:
      # 手动加载
      self.__storeService = storeService
    else:
      # 根据配置加载存储服务
      storeConfig = self.config.get("storeConfig")
      if storeConfig:
        self.storeService = StoreFactory.getStoreService(storeConfig)
    if not self.storeService:
      LogUtil.error(title="存储服务初始化失败")
    return self.storeService

  def initHttpConfig(self, httpConfig=None):
    if not httpConfig:
      httpConfig = self.config.get('httpConfig')

    self.__http = CarHttp(httpConfig=httpConfig)

  # 加载配置文件
  # @timmer
  def initConfig(self, path: str) -> Dict:

    p = path
    if os.path.isfile(p):
      self.config = json5.load(open(p, "r", encoding="utf8"))
      self.mode = self.config.get('mode')

      self.initHttpConfig()
      self.initStoreService()
    else:
      print(f'配置文件[{path}]不存在')
    return self.config

  # 启动应用
  def start(self, *args, **kwargs):

    # 通过配置文件启动模块
    modules = self.config.get("modules")
    CarUtil.loadModules(modules, self, *args, **kwargs)

  #endregion
